﻿using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Windows.Forms;
using WebMoney.WMSignerFX.KeysExtractor.Properties;
using WebMoney.WMSignerFX.KeysExtractor.Utils;
using System.IO;
using WebMoney.SignerFX;
using System.Text;

namespace WebMoney.WMSignerFX.KeysExtractor
{
    public partial class MainForm : Form
    {
        const int HELP_INDEX = 2001;
        private readonly CultureInfo enCulture; // для английского языка
        private readonly CultureInfo ruCulture; // для русского языка

        private CultureInfo _curCulture; // текущая культура

        private object _content;

        public MainForm()
        {
            // инициализируем readonly поля
            enCulture = new CultureInfo("en-US");
            ruCulture = new CultureInfo("ru-RU");
            // восстанавливаем культуру из settings
            _curCulture = LocalizableUtils.LoadCulture();
            // применяем текущую культуру к рабочему потоку
            Thread.CurrentThread.CurrentCulture = _curCulture;
            Thread.CurrentThread.CurrentUICulture = _curCulture;

            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // устанавливаем флажек языка
            setLangSwitcher();
            // устанавливаем название
            Text = AssemblyInfoAccessors.AssemblyTitleShortVersion;
            // устанавливаем статус по умолчанию
            infoStatusLabel.Text = Resources.Done;
        }

        private void wMKeeperClassicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog.Filter = "WM keys' file|*.kwm";

            DialogResult result = openFileDialog.ShowDialog();

            if (DialogResult.OK != result)
                return;

            byte[] keysData;

            try
            {
                keysData = ReadFile.ReadFromName(openFileDialog.FileName);
            }
            catch (ArgumentException ex)
            {
                MessageBox.Show(this, ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);

                return;
            }
            catch (IOException)
            {
                MessageBox.Show(this, Resources.FailedOpenFile, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            IdPasswordForm idPwForm;

            try
            {
                idPwForm = new IdPasswordForm(keysData);
            }
            catch(ArgumentException)
            {
                MessageBox.Show(this, Resources.InvalidFile, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            result = idPwForm.ShowDialog(this);

            if (DialogResult.OK != result)
                return;

            _content = idPwForm.Keys;
            enabled(false);
            setText();
            sendText(Resources.FileOpen);
        }

        private void wMLightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog.Filter = "Personal Information Exchange|*.pfx";

            DialogResult result = openFileDialog.ShowDialog();

            if (DialogResult.OK != result)
                return;

            PasswordForm pwdForm = new PasswordForm();
            DialogResult pwdDlg = pwdForm.ShowDialog(this);

            if (DialogResult.OK != pwdDlg)
                return;

            byte[] content;

            try
            {
                X509Certificate2 cer =
                    new X509Certificate2(openFileDialog.FileName, pwdForm.Password, X509KeyStorageFlags.Exportable);
                
                content = cer.Export(X509ContentType.Pfx, string.Empty);
            }
            catch (CryptographicException)
            {
                MessageBox.Show(this, Resources.WrongData, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            _content = content;
            enabled(true);
            setText();
            sendText(Resources.FileOpen);
        }

        private void wMRootCertificateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog.Filter = "Security Certificate|*.crt";

            DialogResult result = openFileDialog.ShowDialog();

            if (DialogResult.OK != result)
                return;

            byte[] content;

            try
            {
                X509Certificate cer = new X509Certificate(openFileDialog.FileName);
                content = cer.Export(X509ContentType.Cert);
                
            }
            catch (CryptographicException)
            {
                MessageBox.Show(this, Resources.InvalidFile, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            _content = content;
            enabled(true);
            setText();
            sendText(Resources.FileOpen);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            copyText();
        }

        private void base64ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            base64ToolStripMenuItem.Checked = true;
            hexToolStripMenuItem.Checked = false;

            setText();
        }

        private void hexToolStripMenuItem_Click(object sender, EventArgs e)
        {
            base64ToolStripMenuItem.Checked = false;
            hexToolStripMenuItem.Checked = true;

            setText();
        }

        private void mD4HashToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new HashForm(mD4HashToolStripMenuItem.Text, MD4Hash.GetHashString)).Show();
        }

        private void mD5HashToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new HashForm(mD5HashToolStripMenuItem.Text, MD5Hash.GetHashString)).Show();
        }

        private void sHA1HashToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new HashForm(sHA1HashToolStripMenuItem.Text, SHA1Hash.GetHashString)).Show();
        }

        private void viewCertificateStoreToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void englishToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // устанавливаем английский язык
            _curCulture = enCulture;
            setCulture();
            sendText(Resources.LanguageChanged);
        }

        private void russianToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // устанавливаем русский язык
            _curCulture = ruCulture;
            setCulture();
            sendText(Resources.LanguageChanged);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new AboutForm().ShowDialog(this);
        }

        private void helpTopicsToolStripMenuItem_Click(object sender, EventArgs e)
        {

            Help.ShowHelp(this, Resources.HelpFile, HelpNavigator.TopicId, HELP_INDEX.ToString(NumberFormatInfo.InvariantInfo));
            sendText(Resources.HelpContentsOpened);
        }

        private void copyButton_Click(object sender, EventArgs e)
        {
            copyText();
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void sendText(string text)
        {
            mainTimer.Enabled = false;
            infoStatusLabel.Text = text;
            mainTimer.Enabled = true;
        }

        private void mainTimer_Tick(object sender, EventArgs e)
        {
            mainTimer.Enabled = false;
            infoStatusLabel.Text = Resources.Done;
        }

        private void enabled(bool hexModeEnabled)
        {
            resultGroupBox.Enabled = true;
            copyToolStripMenuItem.Enabled = true;
            copyButton.Enabled = true;

            base64ToolStripMenuItem.Enabled = true;

            if (hexModeEnabled)
                hexToolStripMenuItem.Enabled = true;
            else
            {
                hexToolStripMenuItem.Enabled = false;
                
                base64ToolStripMenuItem.Checked = true;
                hexToolStripMenuItem.Checked = false;
            }
        }

        public void setText()
        {
            if (_content is BKeys)
                resultTextBox.Text = _content.ToString();
            else if (_content is byte[])
            {
                byte[] result = (byte[]) _content;

                if (base64ToolStripMenuItem.Checked)
                    resultTextBox.Text = Convert.ToBase64String(result);
                else if (hexToolStripMenuItem.Checked)
                {
                    StringBuilder sResult = new StringBuilder();

                    for (int pos = 0; pos < result.Length; pos++)
                        sResult.Append(string.Format(null, "0x{0:x2}, ", result[pos]));

                    resultTextBox.Text = sResult.ToString().Remove(sResult.Length - 2);
                }
            }
        }

        private void setCulture()
        {
            Thread.CurrentThread.CurrentCulture = _curCulture;
            Thread.CurrentThread.CurrentUICulture = _curCulture;

            LocalizableUtils.TranslateFormTo(this);

            LocalizableUtils.SaveCulture(_curCulture);

            // устанавливаем флажек языка
            setLangSwitcher();

            // устанавливаем название
            Text = AssemblyInfoAccessors.AssemblyTitleShortVersion;
        }

        private void setLangSwitcher()
        {
            switch (_curCulture.ToString())
            {
                case "ru-RU":
                    englishToolStripMenuItem.Checked = false;
                    russianToolStripMenuItem.Checked = true;
                    break;
                default:
                    russianToolStripMenuItem.Checked = false;
                    englishToolStripMenuItem.Checked = true;
                    break;
            }
        }

        private void copyText()
        {
            Clipboard.Clear();
            
            if (string.IsNullOrEmpty(resultTextBox.Text))
                return;

            Clipboard.SetText(resultTextBox.Text);
            sendText(Resources.TextCopiedClipboard);
        }
    }
}